﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace gbL.NetBoard.Filters
{
    public abstract class SymmetricFilterBase<T> : IFilter<T, T>
    {
        public void AddFilter(object owner, T toFilter)
        {
            lock (_filtersLock)
            {
                if (!_filters.ContainsKey(owner)) _filters.Add(owner, BuildFilterList());
                _filters[owner].Add(toFilter);
            }
        }

        public virtual void Precalculate(T toMatch)
        {
            // not needed
        }

        public bool HasFilter(object owner)
        {
            return _filters.ContainsKey(owner);
        }

        public bool IsAllowed(object owner, T toMatch)
        {
            lock (_filtersLock)
            {
                if (!_filters.ContainsKey(owner)) return true;
                return _filters[owner].Any(x => Evaluate(x, toMatch));
            }
        }


        protected virtual IList<T> BuildFilterList() { return new List<T>(); }

        /// <summary>
        /// Func which will receive the filter as the first parameter, and the candidate object as the second parameter
        /// </summary>
        protected abstract Func<T, T, bool> Evaluate { get; }


        private object _filtersLock = new object();

        private Dictionary<object, IList<T>> _filters = new Dictionary<object, IList<T>>();
    }
}
